#ifndef PARAFLUIDVECTOR_H
#define PARAFLUIDVECTOR_H

#include <QDataStream>

namespace ParaFluid
{
	/**
	* A 3D vector defined by it's x, y and z dimensions.
	*/
	class Vector
	{
		
	public:
		
		/**
		* Destructor
		*/
		virtual ~Vector();
		
		/**
		* Default Constructor
		* @note Default values for x, y and z is 0
		*/
		Vector();
		
		/**
		* Constructor with values for x, y and z
		*/
		Vector(float X, float Y, float Z);
		
		/**
		* Copy Constructor
		*/
		Vector(const Vector & other);
		
		/**
		* Assignment Operator
		* @return this
		*/
		Vector & operator= (const Vector & rhs);
		
		/**
		* Comparison Operator
		* @return TRUE if the object is comparable to this
		*/
		bool operator== (const Vector & rhs) const;
		
		/**
		* Add a Vector
		* @return A new Vector that is the result of the addition
		*/
		Vector operator+ (const Vector & rhs) const;
		
		/**
		* Add a Vector to this
		* @return this
		*/
		Vector & operator+= (const Vector & rhs);
		
		/**
		* Subtract a Vector
		* @return A new Vector that is the result of the subtraction
		*/
		Vector operator- (const Vector & rhs) const;
		
		/**
		* Subtract a Vector to this
		* @return this
		*/
		Vector & operator-= (const Vector & rhs);
		
		/**
		* Multiply a Scalar
		* @return A new Vector that is the result of the multiplication
		*/
		Vector operator* (const float & rhs) const;
		
		/**
		* Multiply a Scalar to this
		* @return this
		*/
		Vector & operator*= (const float & rhs);
		
		/**
		* Dot product (scalar product) with another vector.
		* @return result of the dot product of this and the other vector
		*/
		float operator* (const Vector & rhs) const;
		
		/**
		* Cross product (vectorial product) with another vector.
		* @return result of the cross product of this and the other vector
		*/
		Vector operator^ (const Vector & rhs) const;
		
		/**
		* Cross product (vectorial product) this with another vector.
		* @return this
		*/
		Vector & operator^= (const Vector & rhs);
		
		/**
		* Getter for Vector length
		* @return Vector length
		*/
		float length() const;
		
		/**
		* Reduce to Unitary vector
		*/
		void unitary();
		
		/**
		* Assuming this Vector is a Point, compute the distance to another Point
		* @note Always positive
		*/
		float distanceTo(const Vector & other) const;
		
		/**
		* Dimension along the X axis
		*/
		float x;
		
		/**
		* Dimension along the Y axis
		*/
		float y;
		
		/**
		* Dimension along the Z axis
		*/
		float z;
		
	};
	
}

QDataStream & operator<< (QDataStream & stream, const ParaFluid::Vector & vector);

QDataStream & operator>> (QDataStream & stream, ParaFluid::Vector & vector);

#endif

